package model

import (
	"context"
	"database/sql"
	"portal/internal/errorx"
	"portal/internal/types"

	"github.com/Masterminds/squirrel"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ SysPostModel = (*customSysPostModel)(nil)

type (
	// SysPostModel is an interface to be customized, add more methods here,
	// and implement the added methods in customSysPostModel.
	SysPostModel interface {
		sysPostModel
		withSession(session sqlx.Session) SysPostModel
		InsertGetId(ctx context.Context, session sqlx.Session, data *SysPost)(int64,error)
		GetListByCondition(ctx context.Context, session sqlx.Session, cond *types.ListPostRequest) ([]*SysPost, error)
		CountCondition(ctx context.Context, session sqlx.Session, cond *types.ListPostRequest)(int64,error)
		ExistByPidUid(ctx context.Context, session sqlx.Session, postId int64, userId int64)error
		Edit(ctx context.Context, session sqlx.Session, data *SysPost)error
	}

	customSysPostModel struct {
		*defaultSysPostModel
	}
)

// NewSysPostModel returns a model for the database table.
func NewSysPostModel(conn sqlx.SqlConn) SysPostModel {
	return &customSysPostModel{
		defaultSysPostModel: newSysPostModel(conn),
	}
}

func (m *customSysPostModel) withSession(session sqlx.Session) SysPostModel {
	return NewSysPostModel(sqlx.NewSqlConnFromSession(session))
}

func (m *customSysPostModel) GetListByCondition(ctx context.Context, session sqlx.Session, cond *types.ListPostRequest) ([]*SysPost, error) {
	sb := squirrel.Select("*").From(m.table)
	if len(cond.Status) > 0 {
		sb = sb.Where(squirrel.Eq{"status": cond.Status})
	}
	if len(cond.PostCode) > 0 {
		sb = sb.Where(squirrel.Eq{"post_code": cond.PostCode})
	}
	if len(cond.PostName) > 0 {
		sb = sb.Where(squirrel.Like{"post_name": `%` + cond.PostName + `%`})
	}
	sb.Offset(uint64((cond.PageNum - 1) * cond.PageSize)).Limit(uint64(cond.PageSize))
	sb.OrderBy("post_sort desc")
	query, args, err := sb.ToSql()
	if err != nil {
		return nil, err
	}
	var posts []*SysPost
	if session != nil {
		err = session.QueryRowsPartialCtx(ctx, &posts, query, args...)
	} else {
		err = m.conn.QueryRowsPartialCtx(ctx, &posts, query, args...)
	}
	return posts, err
}

func (m *customSysPostModel) CountCondition(ctx context.Context, session sqlx.Session, cond *types.ListPostRequest)(int64,error){
	sb := squirrel.Select("count(*)").From(m.table)
	if len(cond.Status) > 0 {
		sb = sb.Where(squirrel.Eq{"status": cond.Status})
	}
	if len(cond.PostCode) > 0 {
		sb = sb.Where(squirrel.Eq{"post_code": cond.PostCode})
	}
	if len(cond.PostName) > 0 {
		sb = sb.Where(squirrel.Like{"post_name": `%` + cond.PostName + `%`})
	}
	query, args, err := sb.ToSql()
	if err != nil {
		return 0, err
	}
	var count int64
	if session != nil {
		err = session.QueryRowPartialCtx(ctx, &count, query, args...)
	} else {
		err = m.conn.QueryRowPartialCtx(ctx, &count, query, args...)
	}
	return count, err
}

func (m *customSysPostModel)ExistByPidUid(ctx context.Context, session sqlx.Session, postId int64, userId int64)error{
	sb := squirrel.Select("1").From("sys_user_post").
			Where(squirrel.Eq{"post_id":postId}).
			Where(squirrel.Eq{"user_id":userId}).
			Limit(1)
	query,args,err := sb.ToSql()
	if err != nil {
		return err
	}
	var count int64
	if session != nil {
		err = session.QueryRowPartialCtx(ctx, &count, query, args...)
	} else {
		err = m.conn.QueryRowPartialCtx(ctx, &count,query, args...)
	}
	if err != nil || count <= 0 {
		return errorx.SqlExistError
	}
	return nil
}

func (m *customSysPostModel)InsertGetId(ctx context.Context, session sqlx.Session, data *SysPost)(int64,error){
	query, args, err := squirrel.Insert(m.table).Columns(sysPostInsertRows).
		Values(data.PostCode,data.PostName,data.PostSort,data.Status,data.CreateBy,data.CreateTime,data.UpdateBy,data.UpdateTime,data.Remark).
		ToSql()
	if err != nil {
		return 0, err
	}
	var sqlRes sql.Result
	if session != nil {
		sqlRes,err = session.ExecCtx(ctx, query, args...)
	} else {
		sqlRes,err = m.conn.ExecCtx(ctx, query, args...)
	}
	if err != nil {
		return 0, err
	}
	id,err := sqlRes.LastInsertId()
	return id, err
}

func (m *customSysPostModel)Edit(ctx context.Context, session sqlx.Session, data *SysPost)error{	
	
	query,args,err := squirrel.Update(m.table).
		SetMap(
			squirrel.Eq{
				"post_code":data.PostCode,
				"post_name":data.PostName,
				"post_sort":data.PostSort,
				"status":data.Status,
				"update_time":data.UpdateTime,
				"update_by":data.UpdateBy,
			}).
		Where(squirrel.Eq{"post_id":data.PostId}).
		ToSql()
	if err != nil {
		return err
	}
	if session != nil {
		_,err = session.ExecCtx(ctx, query, args...)
	} else {
		_,err = m.conn.ExecCtx(ctx, query, args...)
	}
	return err
}